#include "pyvim.h"


PyDoc_STRVAR(segments_doc,
"A segments class descript more than one segment\n");

static PyObject *
segments_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
	return type->tp_alloc(type, 0);
}

static int
segments_init(PvSegments *self, PyObject *args, PyObject *kwds)
{
	self->segments = PyDict_New();
	if (self->segments == NULL)
		return -1;

	return 0;
}

static void
segments_dealloc(PyObject *self)
{
	Py_XDECREF(SEG_SET(self));
}

static PyObject *
PvSegments_Push(PyObject *self, int lnum, int start, int end)
{
	PyObject *segs, *plnum;
	PyObject *item;
	int i, len;
	int s, e, r, oldpos;
	int unioned = 0;

	assert(start <= end);

	plnum = PyLong_FromLong(lnum);
	segs = PyDict_GetItem(SEG_SET(self), plnum);
	if (segs == NULL) {
		segs = PyList_New(0);
		PyList_Append(segs, Py_BuildValue("(ii)", start, end));
		PyDict_SetItem(SEG_SET(self), plnum, segs);
		Py_RETURN_NONE;
	} else
		len = PyList_Size(segs);

	for (i = 0; i < len; i++) {
		item = PyList_GetItem(segs, i);
		if (!PyArg_ParseTuple(item, "ii", &s, &e))
			return NULL;
		r = seg_union(&s, &e, start, end);
		if (r == 1) {
			item = Py_BuildValue("(ii)", s, e);
			PyList_SetItem(segs, i, item);
			if (unioned == 0) {
				unioned = 1;
				oldpos = i;
			} else {
				PySequence_DelItem(segs, oldpos);
				i--;
				len--;
			}
			start = s;
			end = e;
		} else if (r == 0) 
			Py_RETURN_NONE;
	}
	if (unioned == 0) {
		item = Py_BuildValue("(ii)", start, end);
		PyList_Append(segs, item);
	}
	Py_RETURN_NONE;
}

PyDoc_STRVAR(segments_push_doc,
"segments.push(lnum, start, end)\n"
"add a segment to segments\n"
"lnum: line number\n"
"start, end: specified the rang [start, end]\n"
);

static PyObject *
segments_push(PyObject *self, PyObject *args)
{
	int lnum, start, end;
	if (!PyArg_ParseTuple(args, "iii", &lnum, &start, &end))
		return NULL;

	return PvSegments_Push(self, lnum, start, end);
}

static PyGetSetDef segments_getseters[] = {
	//{"length", (getter)buffer_getlength, (setter)buffer_setlength, 
	//	"The total number of buffer lines"},
	{NULL}
};

static PyMemberDef segments_members[] = {
	{"segs", T_OBJECT, offsetof(PvSegments, segments), 0, 
		"storage all segments"},
	{NULL}
};

static PyMethodDef segments_methods[] = {
	{"push", (PyCFunction)segments_push, METH_VARARGS,
		segments_push_doc},
	{NULL, NULL}
};


PyTypeObject PvSegments_Type = {
	PyObject_HEAD_INIT(0)
        "pyvim.segment",		/* tp_name */
        sizeof(PvSegments),		/* tp_basicsize */
        0,				/* tp_itemsize */
        segments_dealloc,		/* tp_dealloc */
        0,				/* tp_print */
        0,				/* tp_getattr */
        0,				/* tp_setattr */
        0,				/* tp_reserved */
        0,				/* tp_repr */
        0,				/* tp_as_number */
        0,				/* tp_as_sequence */
        0,				/* tp_as_mapping */
        0,				/* tp_hash */
        0,				/* tp_call */
        0,				/* tp_str */
        PyObject_GenericGetAttr,	/* tp_getattro */
        0,				/* tp_setattro */
        0,				/* tp_as_buffer */
        Py_TPFLAGS_DEFAULT,		/* tp_flags */
        segments_doc,		/* tp_doc */
        0,				/* tp_traverse */
        0,				/* tp_clear */
        0,				/* tp_richcompare */
        0,				/* tp_weaklistoffset */
        0,				/* tp_iter */
        0,				/* tp_iternext */
        segments_methods,		/* tp_methods */
        segments_members,				/* tp_members */
        segments_getseters,				/* tp_getset */
        0,				/* tp_base */
        0,				/* tp_dict */
        0,				/* tp_descr_get */
        0,				/* tp_descr_set */
        0,				/* tp_dictoffset */
        (initproc)segments_init,				/* tp_init */
        0,				/* tp_alloc */
        segments_new,				/* tp_new */
        0,				/* tp_free */
        0,				/* tp_is_gc */
};

/*
Local variables:
c-basic-offset: 4
indent-tabs-mode: nil
End:
*/
